<?php

class Helper_Mail
{

    /**
     * @var array
     */
    protected $_options = array();

    /**
     * zend mail transport
     * @var Zend_Mail_Transport_Abstract
     */
    protected $_transport = null;

    /**
     * constructor
     * @return void
     */
    public function __construct()
    {
        $this -> _options =
        include NUO_SETTING_PATH . '/mail.php';
    }

    /**
     * create an email
     * @usage:
     * 1. send('core.test-mail-setting','nam.ngvan@gmail.com')
     * 2. send('core.test-mail-setting',array('nam.ngvan@gmail.com','nam
     * nguyen'))
     * 2. send(array('param1, param2, param3'),1,)
     *
     * @param array/string $params
     * @param array/string/int $to
     * @param array $extra
     * @return Core_Plugin_Helper_Mail
     */
    public function send($name, $to, $params = null)
    {

        /**
         * @var array
         */
        $tos = $this -> _getReceipients($to);

        if (empty($tos))
        {
            throw new Exception("invalid mail, no receipient imput.");
        }

        /**
         * @var email template
         */
        $template = $this -> getTemplate($name);

        if (!is_object($template))
        {
            throw new Exception("no email template associate with name $name.");
        }

        /**
         * parse to array of data
         */
        $data = $template -> parse($params);

        $subject = $template -> compileSubject($data);
        $body = $template -> compileBody($data);

        /**
         * get mail template objet then process it with data if you need.
         */

        if (null == $subject)
        {
            throw new Exception("invalid mail, mail subject is emptpy");
        }

        if (null == $body)
        {
            throw new Exception("invalid mail, mail body is emptpy");
        }

        $mail = $this -> createMail();
        
        $fromEmail = (isset($params['from_email']) && !empty($params['from_email'])) ? $params['from_email'] : $this -> getOption('from-email');
        $fromName = (isset($params['from_name']) && !empty($params['from_name'])) ? $params['from_name'] : $this -> getOption('from-name');
        $replyEmail = (isset($params['reply_email']) && !empty($params['reply_email'])) ? $params['reply_email'] : $this -> getOption('reply-email');
        $replyName = (isset($params['reply_name']) && !empty($params['reply_name'])) ? $params['reply_name'] : $this -> getOption('reply-name');

        $mail -> setFrom($fromEmail, $fromName) -> setReplyTo($replyEmail, $replyName) -> setSubject($subject);

        foreach ($tos as $to)
        {
            $mail -> addTo($to[0], $to[1]);
        }

        $mail -> setBodyHtml($body);

        /**
         * check to use body html
         */
        $mail -> send($this -> getTransport());
    }

    protected function getTemplate($name)
    {
        // get email template from name.
        $table = Nuo::getTable('core@mail.template');
        return $table -> fetchRow($table -> select() -> where('name=?', strtolower($name)));
    }

    /**
     * return format [array[email,name]]
     * @param string/array $tos
     * @return array
     */
    protected function _getReceipients($tos)
    {
        $ret = array();

        if (is_string($tos) || is_int($tos))
        {
            $to = $this -> _getReceipient($tos);
            /**
             * email exists
             */
            if ($to[0])
            {
                $ret[] = $to;
            }
        }
        else
        if (is_array($tos))
        {
            foreach ($tos as $to)
            {
                $to = $this -> _getReceipient($tos);
                /**
                 * email exists
                 */
                if ($to[0])
                {
                    $ret[] = $to;
                }

            }
        }
        return $ret;
    }

    /**
     * check to and get the information
     * return format [email,name]
     * @see core/model/table/mail/receipient
     * @param string/int/array $to
     * @return array
     */
    protected function _getReceipient($to)
    {

        /**
         * @var string
         */
        $email = $name = null;

        /**
         * not email address
         */
        if (is_string($to) || is_int($to))
        {
            // is user id is detected
            if (false == strpos($to, '@'))
            {
                $table = Nuo::getTable('user@user');
                $row = $table -> fetchRow($table -> select() -> where('uid=?', $to));
                if (is_object($row))
                {
                    $email = $row -> email;
                    $name = $row -> name;
                }
                else
                {
                    $table = Nuo::getTable('core@mail.receipient');
                    $row = $table -> fetchRow($table -> select() -> where('id=?', $to));
                    if (is_object($row))
                    {
                        $email = $row -> email;
                        $name = $row -> name;
                    }
                }
            }
            else// is email address.
            {
                $row = $table -> fetchRow($table -> select() -> where('email=?', $to));

                if (is_object($row))
                {
                    $email = $row -> email;
                    $name = $row -> name;
                }
                else
                {
                    $email = $to;
                }
            }

        }
        else
        if (is_array($to))
        {
            if (isset($to['email']))
            {
                $email = $to['email'];
            }
            else
            if (isset($to[0]) && strpos($to[0], '@'))
            {
                $email = $to[0];
            }
            if (isset($to['name']))
            {
                $name = $to['name'];
            }
            else
            if (isset($to[1]))
            {
                $name = $to[1];
            }
        }
        return array(
            $email,
            $name
        );
    }

    /**
     * send a mail
     * @param Zend_Mail $mail
     * @return Core_Plugin_Helper_Mail
     */
    protected function _doSend(Zend_Mail $mail)
    {
        /**
         * place this mail then send to process.
         */

    }

    /**
     * get options
     * @return array
     */
    public function getOptions()
    {
        return $this -> _options;
    }

    /**
     * set options
     * @param arrray $options
     * @return Core_Plugin_Helper_Mail
     */
    public function setOptions($options)
    {
        $this -> _options = $options;
        return $this;
    }

    /**
     * get option
     * @param string $name
     * @param string/array $default
     * @return string/array
     */
    public function getOption($name, $default = null)
    {
        return isset($this -> _options[$name]) ? $this -> _options[$name] : $default;
    }

    /**
     * get mail transport
     * @return Zend_Mail_Transport_Abstract
     */
    public function getTransport($setting = null, $reset = false)
    {
        if ($reset || null == $this -> _transport)
        {

            if (null == $setting)
            {
                $setting = $this -> getOption('adapter', array(
                    'class' => 'Zend_Mail_Transport_Sendmail',
                    'args' => array(),
                ));
            }

            $args = (!empty($setting['args']) ? $setting['args'] : array());

            $r = new ReflectionClass($setting['class']);

            $this -> _transport = $r -> newInstanceArgs($args);

            if (!$this -> _transport instanceof Zend_Mail_Transport_Abstract)
            {
                throw new Exception("Invalid Transport protocol.");
            }
        }

        return $this -> _transport;
    }

    /**
     * create a mail object
     * @return Zend_Mail
     */
    public function createMail()
    {
        return new Zend_Mail('utf-8');
    }

}
